package com.pompom.workers;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import nl.ansuz.android.steam.dota.request.DotaRequest;
import nl.ansuz.android.steam.dota.request.match.GetMatchHistory;
import nl.ansuz.android.steam.dota.request.match.GetMatchHistoryBySequenceNum;
import nl.ansuz.android.steam.dota.response.match.GetMatchDetailsResponse;
import nl.ansuz.android.steam.dota.response.match.GetMatchHistoryBySequenceNumResponse;
import nl.ansuz.android.steam.dota.response.match.GetMatchHistoryResponse;
import nl.ansuz.android.steam.request.SteamRequest;
import nl.ansuz.android.steam.util.GsonUtil;

import com.google.gson.Gson;
import com.pompom.matchcrawler.JobManager;
import com.pompom.matchcrawler.MPBuffer;
import com.pompom.matchcrawler.ManipulaHttp2;
import com.pompom.matchcrawler.MatchPersistor;
import com.pompom.matchcrawler.types.TOMatchErrorQueue;
import com.pompom.matchcrawler.types.TOMatchWorkQueue;

public class NewLatestMatchesWorker extends AbstractWorker{



	private int maxIte=0;
	private int backMinutes=0;
	private int minMinutes=30;
	private int maxMinutes=60;
	private int contMinutes;
	private long matchesPerMin=60;
	private long forceStartMatch=0;
	private long limitMatch=Long.MAX_VALUE;
	private int persistorBufferSize=50;
	public NewLatestMatchesWorker()
	{

	}
	public NewLatestMatchesWorker(long forceStartMatch)
	{
		this.forceStartMatch=forceStartMatch;
		System.out.println("force started "+forceStartMatch);
	}

	private long latestMatch=0; 
	private boolean calibrated=false;

	private void calibrate()
	{
		calibrated=true;
		GetMatchHistoryResponse matchHistory = fetchLatestMatchesForCalibration(); 
		latestMatch=0;
		for (int i=0;i<matchHistory.matches.length;i++)
		{
			if (matchHistory.matches[i].matchSequenceNumber>latestMatch)
				latestMatch =  matchHistory.matches[i].matchSequenceNumber;
		}


		System.out.println("calibrated "+matchHistory.matches[0].matchSequenceNumber+" "+new Date(matchHistory.matches[0].startTime)+" "+matchHistory.matches[0].startTime);

	}

	public void work()
	{


		long startIn=-1;
		int iteCount=0;


		boolean hasNewRecords = true;


		if (forceStartMatch==0)
		{
			if (!calibrated)
				calibrate();


			latestMatch = latestMatch - matchesPerMin*backMinutes;
		}
		else
			latestMatch=forceStartMatch;


		GetMatchHistoryBySequenceNumResponse matchHistory =null;

		boolean sleep=false;
		int itecont=0;
		while (true)
		{
			if (sleep)
			{
				//System.out.println("limit reached! sleep");
				try {
					Thread.sleep(11000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				sleep=false;
			}


			matchHistory = fetch( latestMatch);

			if (matchHistory==null || matchHistory.matches==null)
				continue;

			if (matchHistory.matches.length==0)
			{
				System.out.println("no matches returned. sleep");
				sleep=true;				
				continue;
			}

			MatchPersistor mpersistor = new MatchPersistor();
			mpersistor.setBufferSize(persistorBufferSize);
			MatchProcessorThread mpt = new MatchProcessorThread(matchHistory, mpersistor); 
			Thread t = new Thread(mpt);
			t.run();




			latestMatch= matchHistory.matches[matchHistory.matches.length-1].matchSequenceNumber;
			if (latestMatch>limitMatch)
			{
				System.out.println("limit "+limitMatch+" reached "+latestMatch);
				this.setStopWork(true);
			}
			//
			if (jobManager.isStopWork()||isStopWork())
				break;


			if (!sleep)
			{
				if (itecont==0)
				{
					limitMatch=latestMatch+500;
					System.out.println("Spawning new worker "+(limitMatch));
					NewLatestMatchesWorker worker = new NewLatestMatchesWorker(limitMatch);
					worker.setJobManager(this.getJobManager());
					jobManager.addWorker(worker);

				}
				itecont++;
			}
		}
		this.setStopWork(true);
		System.out.println("job "+limitMatch+" hasstopped"); 

	}






	@Override
	public void setParameters() { 
		if (getParameter("maxIte")!=null)
		{
			maxIte = Integer.parseInt(getParameter("maxIte"));
		}
		if (getParameter("minMinutes")!=null)
		{
			minMinutes = Integer.parseInt(getParameter("minMinutes"));
		}
		if (getParameter("maxMinutes")!=null)
		{
			maxMinutes = Integer.parseInt(getParameter("maxMinutes"));
		}

		if (getParameter("backMinutes")!=null)
		{
			backMinutes = Integer.parseInt(getParameter("backMinutes"));
		}

		if (getParameter("matchesPerMin")!=null)
		{
			backMinutes = Integer.parseInt(getParameter("matchesPerMin"));
		}

		if (getParameter("forceStartMatch")!=null)
		{
			forceStartMatch = Integer.parseInt(getParameter("forceStartMatch"));
		}
		if (getParameter("BUFFER_SIZE")!=null)
		{
			persistorBufferSize = Integer.parseInt(getParameter("BUFFER_SIZE"));
		}

	}

	private GetMatchHistoryBySequenceNumResponse   fetch( long startMatch)
	{
		GetMatchHistoryBySequenceNum getMatchHistory = new GetMatchHistoryBySequenceNum();
		Map<String, String> params = new HashMap<String, String>();
		params.put(SteamRequest.Parameter.API_KEY, "18755ABB58C0BE96815AE471FBB1C3F2");  

		params.put("start_at_match_seq_num",""+startMatch);


		String url = getMatchHistory.createRequestUrl(DotaRequest.ApplicationID.LIVE, params);

		String response="";
		GetMatchHistoryBySequenceNumResponse getMatchHistoryResponse =null;
		while (getMatchHistoryResponse==null)
		{
		try {
			response = ManipulaHttp2.executaConsulta(url);
		} catch (IOException e) { 
			e.printStackTrace();
		}  
		GsonUtil gsonUtil = new GsonUtil();

		Gson gson = new Gson(); 

			try{
				getMatchHistoryResponse = gson.fromJson(gsonUtil.getStrippedDotaResult(response), GetMatchHistoryBySequenceNumResponse.class);
			}
			catch (Exception e)
			{
				System.out.println("malffformed json");
				try {
					Thread.sleep(500);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} 

		}



		return getMatchHistoryResponse;
	}





	private GetMatchHistoryResponse   fetchLatestMatchesForCalibration( )
	{
		GetMatchHistory getMatchHistory = new GetMatchHistory();
		Map<String, String> params = new HashMap<String, String>();
		params.put(SteamRequest.Parameter.API_KEY, "18755ABB58C0BE96815AE471FBB1C3F2");  

		String url = getMatchHistory.createRequestUrl(DotaRequest.ApplicationID.LIVE, params);


		String response="";
		GetMatchHistoryResponse getMatchHistoryResponse =null;
		while (getMatchHistoryResponse==null)
		{
		try {
			response = ManipulaHttp2.executaConsulta(url);
		} catch (IOException e) { 
			e.printStackTrace();
		} 

		GsonUtil gsonUtil = new GsonUtil();

		Gson gson = new Gson(); 

			try{
				getMatchHistoryResponse = gson.fromJson(gsonUtil.getStrippedDotaResult(response), GetMatchHistoryResponse.class);
			}
			catch (Exception e)
			{
				System.out.println("malffformed json");
				try {
					Thread.sleep(500);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

		}
		return getMatchHistoryResponse;
	}



}
